<?php
// 应用公共文件
function encrypt($txt, $key = '', $expiry = 0)
{
    strlen($key) > 5 or $key = DT_KEY;
    $str = $txt . substr($key, 0, 3);
    return str_replace(array('=', '+', '/', '0x', '0X'), array('-E-', '-P-', '-S-', '-Z-', '-X-'), mycrypt($str, $key, 'ENCODE', $expiry));
}

function decrypt($txt, $key = '')
{
    strlen($key) > 5 or $key = DT_KEY;
    $str = mycrypt(str_replace(array('-E-', '-P-', '-S-', '-Z-', '-X-'), array('=', '+', '/', '0x', '0X'), $txt), $key, 'DECODE');
    return substr($str, -3) == substr($key, 0, 3) ? substr($str, 0, -3) : '';
}

function mycrypt($string, $key, $operation = 'DECODE', $expiry = 0)
{
    $ckey_length = 4;
    $key = md5($key);
    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);
    $result = '';
    $box = range(0, 255);
    $rndkey = array();
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }
    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if ($operation == 'DECODE') {
        if ((substr($result, 0, 10) == 0 || intval(substr($result, 0, 10)) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    } else {
        return $keyc . base64_encode($result);
    }
}

function myswitch($kvalue, $array)
{
    return isset($array[$kvalue]) ? $array[$kvalue] : '';
}

function post($url, $post_data, $header = [])
{
    //初始化
    $curl = curl_init();
    //设置抓取的url
    curl_setopt($curl, CURLOPT_URL, $url);
    //设置头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, 0);
    //设置获取的信息以文件流的形式返回，而不是直接输出。
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    //设置post方式提交
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data));
    if ($header) curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    //执行命令
    $data = curl_exec($curl);
    //关闭URL请求
    curl_close($curl);
    //显示获得的数据
    return $data;
}

//https://cloud.tencent.com/document/product/266/10638
function get_signature($sign_token)
{
    $arg_list = [
        "expireTime" => time() + 14400,
        "random" => rand(),
    ];
    $original = http_build_query($arg_list);
    return base64_encode(hash_hmac('SHA1', $original, $sign_token, true) . $original);
}

function check_signature($signature, $sign_token)
{
    $signature = base64_decode($signature);
    if ($signature === false) return false;
    $hash = substr($signature, 0, 20);
    $original = substr($signature, 20);
    parse_str($original, $arg_list);
    if (!isset($arg_list['expireTime'])) return false;
    if (time() > $arg_list['expireTime']) return false;
    return $hash == hash_hmac('SHA1', $original, $sign_token, true);
}

function form_signature($name = '__signature__')
{
    $config = config('api');
    $signature = get_signature($config['auth_key']);
    return "<input type=\"hidden\" name=\"{$name}\" value=\"{$signature}\" />";
}

//rsa加密
function rsa_encode()
{
    $data = [
        'time' => time(),
        'key' => md5(microtime(true)),
    ];
    $data = json_encode($data);
    Rsa::$pubkey = app()->getRootPath() . '/cert/rsa_1024_pub.pem';
    Rsa::$privkey = app()->getRootPath() . '/cert/rsa_1024_priv.pem';
    return Rsa::publicEncrypt($data);
}

//rsa解密
function rsa_decode($str)
{
    Rsa::$pubkey = app()->getRootPath() . '/cert/rsa_1024_pub.pem';
    Rsa::$privkey = app()->getRootPath() . '/cert/rsa_1024_priv.pem';
    $data = Rsa::privDecrypt($str);
    if ($data === null) return false;
    $data = json_decode($data, true);
    if (time() - 60 > $data['time']) {
        return false;
    }
    return true;
}